rust 多平台demo
rust 安装
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh |
提高init速度
export RUSTUP_DIST_SERVER="https://mirrors.ustc.edu.cn/rust-static" |
换源
编辑$HOME/.cargo/config.toml
[source.crates-io] |
vscode配置
check commond : check 改为 clippy ,以防止rust_analyzer卡
版本切换
在使用SIMD进行加速时,需要使用nightly版本
rustup update nightly |
查看是否配置成功
rustc --version |
输出:rustc 1.84.0-nightly (798fb83f7 2024-10-16)
C++
第一步:创建Rust库
新建Rust库项目:
cargo new rust_tokenizer --lib
cd rust_tokenizer编辑
Cargo.toml
: 添加如下内容,以确保生成动态链接库:[lib]
name = "rust_tokenizer"
crate-type = ["cdylib"]编写Rust代码: 在
src/lib.rs
中添加你的tokenizer逻辑,同时提供一个C兼容的接口。下面是一个简单的例子,使用Rust实现一个基础的tokenizer函数。use std::ffi::{CString, CStr};
use std::os::raw::c_char;
#[no_mangle]
pub extern "C" fn tokenize(text: *const c_char) -> *mut c_char {
let c_str = unsafe {
assert!(!text.is_null());
CStr::from_ptr(text)
};
let r_str = c_str.to_str().unwrap();
let tokenized = r_str.replace(" ", "|"); // 简单的tokenization逻辑
CString::new(tokenized).unwrap().into_raw()
}
#[no_mangle]
pub extern "C" fn free_string(s: *mut c_char) {
unsafe {
if s.is_null() { return }
CString::from_raw(s)
};
}这里我们定义了两个函数:
tokenize
用于处理字符串,free_string
用于释放Rust分配的内存。编译Rust代码:
cargo build --release
编译后的
.so
文件位于target/release
目录下。
第二步:在C++中调用Rust函数
编写C++代码: 在C++项目中,使用Rust编译出的
.so
库文件。#include <iostream>
extern "C" {
char* tokenize(const char* text);
void free_string(char* s);
}
int main() {
const char* text = "Hello, world!";
char* result = tokenize(text);
std::cout << "Tokenized: " << result << std::endl;
free_string(result);
return 0;
}编译C++代码: 使用g++编译,并链接Rust生成的
.so
文件。
g++ -o tokenizer_test main.cpp -L/path/to/target/release -lrust_tokenizer -ldl运行C++程序: 确保Rust生成的
.so
文件路径在LD_LIBRARY_PATH环境变量中,或者复制到合适的位置。export LD_LIBRARY_PATH=/path/to/target/release:$LD_LIBRARY_PATH
./tokenizer_test
C++ 交叉编译
1.rust配置
添加目标架构 aarch64-unknown-linux-gnu
(适用于 ARM64 的 Linux):
rustup target add aarch64-unknown-linux-gnu |
2. 安装交叉编译工具链
需要一个交叉编译工具链来生成适用于 ARM64 架构的二进制文件。在 Debian/Ubuntu 上,可以安装以下工具:
sudo apt-get update |
3. 配置和编译
在项目的根目录下创建一个文件 .cargo/config.toml
,以配置交叉编译工具链:
[target.aarch64-unknown-linux-gnu] |
接下来,运行以下命令进行编译:
cargo build --release --target=aarch64-unknown-linux-gnu |
编译完成后, .so
文件将在 target/aarch64-unknown-linux-gnu/release/
目录下。
4.使用自定义工具链
在项目的根目录下创建 .cargo/config.toml
文件:
[target.aarch64-unknown-linux-gnu] |
设置环境变量以指定工具链的 sysroot 和相关库路径:
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=/path/to/custom/toolchain/bin/aarch64-linux-gnu-gcc |
5.编译x64通用
rustup target add x86_64-unknown-linux-gnu |
在 Rust 项目中,创建一个适用于更广泛兼容性的 .cargo/config.toml
文件,确保使用的是一个较低版本的 glibc,并且静态链接标准库和其他依赖项:
[target.x86_64-unknown-linux-gnu] |
确保在编译时使用目标为 x86_64-unknown-linux-gnu
:
cargo build --release --target=x86_64-unknown-linux-gnu |
编译ubuntu16.04兼容的python库
docker 安装
https://docs.docker.com/desktop/wsl/#download
拉取docker
docker pull ubuntu:16.04 |
配置rust
curl https://sh.rustup.rs -sSf | sh |
配置Python
cd /home/jw |
编译
cd code/ |
无法安装问题解决:将xxx-0.1.0-cp310-cp310-manylinux_2_24_x86_64.whl更名为xxx-0.1.0-cp310-cp310-manylinux1_x86_64.whl
重启后重新进入
进入环境
docker ps |
激活python环境
micromamba activate [env_name] |
编译
cd code/ |
编译manylinux2014
拉取docker pull quay.io/pypa/manylinux2014_x86_64
创建docker images
sudo docker run -it \
--name manylinux2014 \
--net=host \
-v /home/jw:/home/jw \
-v code:/code \
quay.io/pypa/manylinux2014_x86_64
配置环境yum install -y curl && \
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && \
source $HOME/.cargo/env
yum groupinstall -y "Development Tools"
yum install -y hdf5 hdf5-devel
配置Python
cd /home/jw |
编译cd code/rust
maturin build --release --manylinux=2014 --out dist
c++和python接口应用实例
1. 配置 Cargo.toml
首先,在Rust 项目的 Cargo.toml
文件中添加 pyo3
和 maturin
依赖:
[package] |
pyo3和maturin
用于python接口,cdylib用于c++接口
2. 编写 Rust 代码
在 src/lib.rs
中编写 Rust 代码,将现有功能同时暴露给 Python 和 C++:
use pyo3::prelude::*; |
3. 构建和发布
使用 maturin
来构建和发布 Python 包。确保安装了 maturin
:
pip install maturin |
在项目根目录下运行以下命令来构建 Python 包:
maturin develop --release |
这将构建并安装 Rust 扩展模块,使其可以在 Python 中导入和使用。
错误解决:pkg_config 错误
sudo apt install pkg-config |
错误解决:ssl 错误
sudo apt install libssl-dev |
4. 编写 Python 接口
现在,可以在 Python 中导入并使用这个包装器模块。以下是一个简单的 Python 接口示例:
import tokenizers_wrapper |
5. 编写 C++ 接口
创建一个简单的 C++ 项目来使用这个包装器模块:
#include <iostream> |
6. 构建和运行 C++ 项目
创建一个 CMakeLists.txt
文件来构建 C++ 项目:
cmake_minimum_required(VERSION 3.18) |
然后,使用 CMake 构建和运行项目:
mkdir build |
rust调用c++
编写mnn_adapter.cpp并编译成so文件
extern "C" { |
编译
gcc -fPIC -shared mnn_adapter.cpp -o libmnn_adapter.so |
编写build.rs
extern crate dunce; |
编写main.rs
|
编写cargo.yml
[package] |
export LD_LIBRARY_PATH=./variable |
MNN示例
build.rs
extern crate dunce; |
wapper.h
#include "MNN/Interpreter.hpp" |
mnn_adapter.cpp
#include "wrapper.h" |
lib.rs
#![allow(non_snake_case)] |
main.rs
extern crate rust_demo; |
c++调用rust
cbindgen自动生成header文件
安装
cargo install cbindgen |
编写cbindgen.toml
header = "// SPDX-License-Identifier: MIT OR Apache-2.0" |
在cargo.toml中添加(后面测试好像不用加)
[package.metadata.capi.header] |
运行
cbindgen --config cbindgen.toml --crate condition_se --output ../src/condition_se_cc.h |
出现问题跨项目类型依赖时,无法导出NoiseType
在cbindgen.toml中添加
[parse] |
rust 运行bin
cargo run --bin aec --release |
使用feature
cargo run --bin aec --release --features="aec bin" |
rust的jupyter
为了便于进行算法模块测试,使用jupyter更方便
安装jupyter lab
conda install -c conda-forge jupyterlab |
安装 evcxr
cargo install evcxr_jupyter |
基础语法
#导入 |
let values = (1..13).map(fib).collect::<Vec<i32>>(); |
显示所有变量 |
自定义显示
use std::fmt::Debug; |
let m = Matrix {values: vec![1,2,3,4,5,6,7,8,9], row_size: 3}; |
显示图片
:dep image = "0.23" |
配置jupyter lab代码补全(vscode更好用)
|
设置
依次点击Settings—>Settings Editor—>Code Completion(第二个)—>打开Enable autocompletion
无法编译,无法启动
通常是因为环境有冲突,与其找原因不如直接删除缓存,重新编译
sudo rm -r ~/.cargo/registry/ |
hdf5编译出错
apt install libhdf5-dev |
ort 的rocm模式
重装rocm
# Uninstall single-version ROCm packages |
安装参考rocm环境配置,可以安装6.0.2
编译onnxruntime
ONNXRUNTIME_REPO=https://github.com/Microsoft/onnxruntime |